home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Stolen Data 3
/
Stolen Data 3.adf
/
SOURCE
/
Scroller1.bak
< prev
next >
Wrap
Text File
|
1988-12-31
|
12KB
|
348 lines
*****************************************************************************
; STOLEN DATA Issue #3
; ~~~~~~~~~~~~~~~~~~~~
; Double buffered one bitplane scroller
;
; Copyright ANARCHY 1990
;
; Written on 3.6.90 by Kreator of ANARCHY
;
; This type of scroller is very efficient speedwise, but causes a number of
; problems, for instance it is difficult to implement variable speeds because
; the charcters are read a long time before they actually appear on screen.
; However even very large scrollers can be run in a very small amount of
; raster time using this technique.
;
; General notes - At all times (unless specified) a6 points to the custom
; chip registers ($dff000) and a5 points to the list of variables.This allows
; indirect addressing modes to be used, which are much faster than absolute
; addressing and consume less memory. If these registers are needed in the
; course of a routine simply stick them on the stack, and pop them back off
; later.
; Scroller2 is very similar to this one but the scroll routine is not fully
; commented, but uses a technique commonly employed recently to get a base-
; relief 2 bitplane font from a single bitplane font. You'll have to figure
; it out for yourself, but its not difficult.
*****************************************************************************
Incdir DF1:
Include Source/NewCustomReg ; Custom register label equates
Section Scroller,Code_c ; Assemble into chip mem if > ½ meg
TEST = 1 ; Set this if you are only testing the menu
; as it will then return to DEVPAC
Trap_vec0 = $80
Execbase = $4
Oldopen = -$198
Move.l #Start,$80.w ; Trap vector 0
Trap #0 ; Execute trap 0 to give full control of the
Rts ; 68000, needs an RTE to return.
Start
Bsr Killsys ; Disable the operating system
Bsr Setup ; Setup the demo
Bsr Main ; Now run the main demo routines
Bsr Sysreturn ; Return the system to its original state
Moveq.l #0,d0 ; No errors !! A number of people neglect to
; do this, and that causes batch files (such
; as the startup sequence) to bomb out.
Rte ; Return from exception ie. to the instruction after
; the TRAP #0 call.
*****************************************************************************
;Killsys - Disable operating system and interrupts
*****************************************************************************
Killsys
Move.l $4.w,a6 ; Execbase vector
Lea Gfxname(pc),a1 ; Pointer to "graphics.library" into a1
Jsr Oldopen(a6) ; Open this library
Lea Variables,a5 ; Get a pointer to the variable space
Lea $dff000,a6 ; Pointer to custom chips
Move.l d0,a0 ; Address of the graphics library
Move.l 38(a0),Sys_copl(a5) ; Remember the System copperlist
Move Intenar(a6),Int_set(a5) ; System interrupts
Move #$7fff,Intena(a6) ; Now switch off all interrupts
Move.l $6c.w,Vbl_vec(a5) ; System vertical blanking int.
Move Dmaconr(a6),Dma_set(a5) ; System DMA
Move #$7fff,Dmacon(a6) ; Clear all DMA
Move #$87c0,Dmacon(a6) ; Now set the required DMA channels
Rts
Gfxname Dc.b "graphics.library",0
Even
*****************************************************************************
;Sysreturn - Re-enable operating system and interrupts
*****************************************************************************
Sysreturn
Move #$7fff,Intena(a6) ; Clear all interrupts
Move.l Vbl_vec(a5),$6c.w ; Restore VBL interrupt
Move Int_set(a5),d0
Or #$c000,d0
Move d0,Intena(a6) ; Restore system interrupts
Move #$7fff,Dmacon(a6)
Move Dma_set(a5),d0
Or #$8200,d0
Move d0,Dmacon(a6) ; Restore system DMA
Move.l Sys_copl(a5),Cop1lch(a6) ; Restore system copperlist
Clr Copjmp1(a6)
Rts
*****************************************************************************
;Setup - Setup the menu system
*****************************************************************************
Setup
;-- Remove the sprite data (prevents sprite streaks down the screen)
Lea Spr0data(a6),a0
Moveq #7,d0
Clop
Clr.l (a0)
Addq.l #8,a0
Dbf d0,Clop
;-- Clear the scroll area
Lea Screen1,a0
Move #$bff,d0
Clear_scroll
Clr.l (a0)+
Dbf d0,Clear_scroll
;-- Initialise some variables
Move.l #Screen1,Current_bank(a5) ; The two double buffered
Move.l #Screen2,Other_bank(a5) ; scroll areas
Move.l #Scrolltext,Text_pt(a5) ; Initialise the scrolltext
Move #5,Speed(a5) ; Set the scroll speed
Move.l #Clstart,Cop1lch(a6) ; Init. our own copperlist
Clr Copjmp1(a6)
Rts
*****************************************************************************
; Main - Central demo calling routine + mouse button check
*****************************************************************************
Main
Move.l Vposr(a6),d0
And.l #$1ff00,d0
Cmp.l #$00100,d0 ; Wait for vertical position 1
Bne.s Main
Bsr Scroller ; Jump to the scroll routine
Move #$200,d0 ; Small delay loop, this is needed because
.Loop ; in general the scroll routine uses less
Dbf d0,.Loop ; than 1 raster line.As soon as more routines
; are added this is no longer required.
Btst #6,$bfe001 ; Check the left mouse button
Bne.s Main
Rts
*****************************************************************************
; Scroller - The scroller is 80 bytes across of which only 46 are displayed
; at any one time. While one is displayed the other is updated, the last 48
; bytes (ie. 24 charcters) of the displayed scroller are copied into the
; first 48 bytes of the other. Then the remaining 32 bytes (16 characters)
; are plotted, from the scrolltext. Every frame two af these characters are
; copied, so it takes 20 frames to create the new scroll bank, and the banks
; are switched when the scroll pointer exceeds 256 (this pointer is just a
; pixel offset from the start of the displayed scroller) This means that the
; Maximum speed of the scroller is about 256/20 = 12 pixels per frame.
; Scroll_pt - the aforementioned scroll pointer
; Mode - Indicates if we need to copy the old data, or create new data from
; the scrolltext. <12 means copy old data =>12&<20 means use the
; scrolltext =20 means finished updating the scroller.
*****************************************************************************
Scroller
Move Scroll_pt(a5),d0
Add Speed(a5),d0
Cmp #256,d0 ; Do we need a bank change
Blt.s No_bank_change
Move.l Current_bank(a5),a0 ; Swap the display and update
Move.l Other_bank(a5),Current_bank(a5) ; scroll banks
Move.l a0,Other_bank(a5)
Sub #256,d0 ; Reset the scroll pointer
Clr Mode(a5)
No_bank_change
Move d0,Scroll_pt(a5)
Move d0,d1 ; Remember d0 for calculating the shift register
Lsr #4,d0 ; Convert d0 into a byte pointer on a word boundary
Add d0,d0
Add Current_bank+2(a5),d0 ; Add the current
Move d0,Scroll_planes+2 ; Stick it into the bitplane pointers
And #$0f,d1 ; Only first four bits needed for shift register
Eor #$0f,d1 ; Its a right shift so invert the bits as we are
; scrolling left
Move d1,Scroll+2 ; Put it into the BPLCON1 register
Cmp #20,Mode(a5)
Beq No_blitting ; The update screen is ready
Cmp #12,Mode(a5)
Blt Char_scroll ; Move the old characters
New_chars
Moveq #0,d0
Move Mode(a5),d2
Lsl #2,d2 ; Multiply mode by four ( 48-76 )
Move.l Other_bank(a5),a2
Lea (a2,d2),a2 ; Add mode*4 to the update screen pointer
Bsr Read_char ; Read the next character and plot it
Addq.l #2,a2 ; Point to the next screen character position
Bsr Read_char ; Then read another character and plot it
Bra Blit_exit ; Thats it for now.
Read_char
Move.l Text_pt(a5),a0 ; Scrolltext pointer
New_char
Move.b (a0)+,d0
Bne.s Not_a_null ; If 0 then reset the scrolltext pointer
Move.l #Scrolltext,a0
Bra.s New_char ; Read the first character
Not_a_null
Cmp #$20,d0 ; Less than 32, then consider as a space
Bge.s Not_control
Moveq #$20,d0
Not_control
Cmp #$5b,d0 ; Convert lowercase to uppercase
Blt.s Not_lower_case
Sub #$20,d0
Not_lower_case
Move.l a0,Text_pt(a5) ; Save the new scrolltext pointer
Sub #$20,d0
Add d0,d0 ; Convert ascii into a word pointer
Lea Charpos(pc),a0 ; Table of character positions
Move (a0,d0),d1
Lea Font(pc),a1
Lea (a1,d1),a1 ; a1 now points to the required character
; graphic image.
Move.l #-1,Bltafwm(a6)
Move.l a2,Bltdpth(a6)
Move.l a1,Bltapth(a6)
Move.l #$09f00000,Bltcon0(a6) ; Just a direct copy from A to D
Move.l #$0026004e,Bltamod(a6) ; Screen is $50 wide, font is $28 wide
Move #(16<<6)!1,Bltsize(a6) ; 16 pixels deep
Bra Blit_wait ; Wait for the blitter to finish
Char_scroll
Move Mode(a5),d0
Lsl #2,d0
Move.l Other_bank(a5),a0
Move.l Current_bank(a5),a1
Lea (a0,d0),a0
Lea 32(a1,d0),a1
Move.l #-1,Bltafwm(a6)
Move.l a0,Bltdpth(a6)
Move.l a1,Bltapth(a6)
Move.l #$09f00000,Bltcon0(a6)
Move.l #$004c004c,Bltamod(a6)
Move #64*16+2,Bltsize(a6) ; Copy two whole characters at once
Bsr Blit_wait
Blit_exit
Addq #1,Mode(a5) ; Move the mode on one
No_blitting
Rts
Blit_wait
Btst #14,Dmaconr(a6) ; Is the blitter still at work?
Bne.s Blit_wait ; Yes, well carry on waiting then.
Rts
*****************************************************************************
; Copperlist1 for the menu selector screen
; For those readers unfamiliar with my coding, I generally use macros for
; generating my copperlists. These I find to be easier to debug etc. but do
; take a little longer to assemble, obviously though for much larger
; copperlists (such as the background effect on the menu-loader) a generating
; routine should be employed.
*****************************************************************************
Clstart
Wait 0,20 ; Give the processor time to update the cl.
Mov $9a64,Diwstrt
Mov $aad1,Diwstop
Mov $0028,Ddfstrt ; Horizontal scrolling overscan screen
Mov $00d8,Ddfstop ; ie. 368 pixels wide
Mov 0,Color00
Mov $666,Color01
Mov $fff,Color02
Mov $aaa,Color03
Mov 34,Bpl1mod ; Scroller is actually 80 bytes wide
Scroll
Mov 0,Bplcon1
Mov 0,Bplcon2
Scroll_planes
Mov $00,Bpl1ptl
Mov 7,Bpl1pth
Mov $1200,Bplcon0 ; Single bitplane
Wait $fe,$ff
*****************************************************************************
; Binaries
*****************************************************************************
Font
Incbin Binary/Bubble.font ; This font was drawn by KREATOR
; so credit me if you use it
; The following table is used to calculate a pointer to the required
; character and in general must be created by hand. Some coders advocate a
; different approach, which is to have all your characters stacked on top
; of each other and then the pointers are very easy to calculate with a
; multiply. I still prefer this method myself.
Charpos Dc.w $0000,$0002,$0004,$0006,$0008,$000a,$000c,$000e ; !"#$%&'
Dc.w $0010,$0012,$0014,$0016,$0018,$001a,$001c,$001e ;()*+,-./
Dc.w $0020,$0022,$0024,$0026,$0280,$0282,$0284,$0286 ;01234567
Dc.w $0288,$028a,$028c,$028e,$0290,$0292,$0294,$0296 ;89:;<=>?
Dc.w $0298,$029a,$029c,$029e,$02a0,$02a2,$02a4,$02a6 ;@ADCDEFG
Dc.w $0500,$0502,$0504,$0506,$0508,$050a,$050c,$050e ;HIJKLMNO
Dc.w $0510,$0512,$0514,$0516,$0518,$051a,$051c,$051e ;PQRSTUVW
Dc.w $0520,$0522,$0524,$0526 ;XYZ[\]^_
; Zero terminated scrolltext, allows a mixture of upper and lower case
; although all the text will be displayed in uppercase. Also you can edit
; the text in any text editor, as the scroller counts all control characters
; such as 10 (line feed) as spaces.
Scrolltext
Dc.b "insert your own scrolltext here !!!"
Dc.b " this scroller was written for "
Dc.b "STOLEN DATA, copyright ANARCHY 1990"
Dc.b " ",0
Even
*****************************************************************************
; Variables
*****************************************************************************
Rsreset
Int_set Rs.w 1 ; System interrupts
Dma_set Rs.w 1 ; System DMA channels
Sys_copl Rs.l 1 ; "" copperlist
Vbl_vec Rs.l 1 ; "" vertical blanking interrupt
Scroll_pt Rs.w 1 ; Scroll pointer, offset in pixels
Mode Rs.w 1 ; <12 COPY OLD, >=12 <20 NEW CHARS, =20 STOP
Current_bank Rs.l 1 ; Currently displayed scroller
Other_bank Rs.l 1 ; The update scroller
Text_pt Rs.l 1 ; Pointer to the scrolltext
Speed Rs.w 1 ; Scroll speed (must be less than 12)
Varisize Rs.b 0 ; Simply used to determine how much space is needed
; for the variable list
Variables Dcb.b Varisize ; Reserve space for the variables
;-- Reserve some space for screens etc..
Rsset $70000
Screen1 Rs.b 16*80
Screen2 Rs.b 16*80